package com.lh.process.engine.context;

import com.lh.process.engine.instance.DefaultProcessInstanceCreator;
import com.lh.process.engine.instance.ProcessorInstanceCreator;
import com.lh.process.engine.model.ProcessModel;
import com.lh.process.engine.node.ProcessorDefinition;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author: linghao
 * @since: 2022/10/19
 */
@Slf4j
public class ProcessContextFactory {

    //创建实例的方式，默认是根据node中配置的class进行创建
    public static final ProcessorInstanceCreator defaultProcessInstanceCreator= new DefaultProcessInstanceCreator();
    private List<ProcessModel> modelList;
    private final Map<String, ProcessorDefinition> processorDefinitionMap = new ConcurrentHashMap<>();
    private final ProcessorInstanceCreator instanceCreator;

    public ProcessContextFactory(List<ProcessModel> models) throws Exception {
        this(models,defaultProcessInstanceCreator);
    }

    public ProcessContextFactory(List<ProcessModel> models,ProcessorInstanceCreator processorInstanceCreator) throws Exception {
        this.modelList = models;
        this.instanceCreator = processorInstanceCreator;
        init();
    }

    private void init() throws Exception {
        //检查流程定义的数据
        for(ProcessModel processModel:modelList){
            processModel.check();
        }
        //封装流程实体
        for(ProcessModel processModel:modelList){
            ProcessorDefinition processorDefinition = processModel.build(instanceCreator);
//            log.info("构造流程成功：\n{}", processorDefinition.toStr());
            processorDefinitionMap.put(processorDefinition.getName(), processorDefinition);
        }
    }

    public ProcessContext getContext(String processName) {
        ProcessorDefinition processorDefinition = processorDefinitionMap.get(processName);
        if (processorDefinition == null) {
            throw new IllegalArgumentException("流程["+processName+"]不存在");
        }
        return new ProcessContext(processorDefinition);
    }
}
